﻿' LibWowArmory
' by Ronald M. Clifford (roncli@roncli.com)
' ItemTooltip classes contributed by Lukan Schwigtenberg (sepai69@gmail.com)
'
' This source code is released under the GNU Library General Public License (LGPL) Version 2.1.

Imports System
Imports System.Collections.ObjectModel
Imports System.Collections.Specialized
Imports System.Globalization
Imports System.IO
Imports System.Linq
Imports System.Web
Imports System.Xml.Serialization

Namespace roncliProductions.LibWowArmory.Item.Tooltip

    ''' <summary>
    ''' A class to get tooltip information on an item from the Armory
    ''' </summary>
    ''' <remarks></remarks>
    Public Class ItemTooltip
        Inherits WowArmoryData

#Region "Declarations"

        Private itPage As New Schema.page

#End Region

#Region "Properties"

        ''' <summary>
        ''' The ID number of the item you wish to retrieve from the Armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property ItemID As Integer

        ''' <summary>
        ''' The name of the character whose item you wish to retrieve from the Armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Character As String

        ''' <summary>
        ''' The name of the realm of the character whose item you wish to retrieve from the Armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Realm As String

        ''' <summary>
        ''' The slot of the item to retrieve from the Armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Slot As Enums.ItemSlotType

        ''' <summary>
        ''' The URL that will be used to retrieve the item tooltip information from the Armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property URL As String
            Get
                If String.IsNullOrEmpty(Character) Or String.IsNullOrEmpty(Realm) Then
                    Return String.Format(CultureInfo.InvariantCulture, "http://www.wowarmory.com/item-tooltip.xml?i={0}", ItemID)
                Else
                    Return String.Format(CultureInfo.InvariantCulture, "http://www.wowarmory.com/item-tooltip.xml?i={0}&cn={1}&r={2}&s={3}", ItemID, Character, Realm, CInt(Slot))
                End If
            End Get
        End Property

        ''' <summary>
        ''' Indicates to the inherited class that this request does not require login
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property RequiresLogin As Boolean
            Get
                Return False
            End Get
        End Property

        ''' <summary>
        ''' The name of the item, without any random enchantment suffix
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BaseName As String
            Get
                Return GetItemTooltip.name
            End Get
        End Property

        ''' <summary>
        ''' The name of the item, including the random enchantment suffix, if any
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Name As String
            Get
                If GetItemTooltip.randomEnchantData.Count = 0 Then
                    Return GetItemTooltip.name
                Else
                    Dim strSuffix = GetItemTooltip.randomEnchantData.First.suffix
                    If String.IsNullOrEmpty(strSuffix) Then
                        Return GetItemTooltip.name
                    Else
                        Return String.Format(CultureInfo.InvariantCulture, "{0} {1}", GetItemTooltip.name, strSuffix)
                    End If
                End If
            End Get
        End Property

        ''' <summary>
        ''' The filename of the item's icon
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Icon As String
            Get
                Return GetItemTooltip.icon
            End Get
        End Property

        ''' <summary>
        ''' The quality of the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Quality As Enums.RarityType
            Get
                Return CType(GetItemTooltip.overallQualityId, Enums.RarityType)
            End Get
        End Property

        ''' <summary>
        ''' The bonding type of the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Bonding As Enums.BondingType
            Get
                Return CType(GetItemTooltip.bonding, Enums.BondingType)
            End Get
        End Property

        ''' <summary>
        ''' Determines if the item is account bound
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property AccountBound As Boolean
            Get
                Return GetItemTooltip.accountBound = 1
            End Get
        End Property

        ''' <summary>
        ''' The instance the item is bound to
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property InstanceBound As String
            Get
                Return GetItemTooltip.instanceBound
            End Get
        End Property

        ''' <summary>
        ''' The zone the item is bound to
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property ZoneBound As String
            Get
                Return GetItemTooltip.zoneBound
            End Get
        End Property

        ''' <summary>
        ''' The maximum amount of items that can be in one stack
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>Returns 0 if the item cannot be stacked</remarks>
        Public ReadOnly Property Stackable As Integer
            Get
                Return GetItemTooltip.stackable
            End Get
        End Property

        ''' <summary>
        ''' The class of the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property [Class] As Enums.ItemClassType
            Get
                Return CType(GetItemTooltip.classId, Enums.ItemClassType)
            End Get
        End Property

        ''' <summary>
        ''' The minimum level required to use the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RequiredLevel As Integer
            Get
                Return GetItemTooltip.requiredLevel
            End Get
        End Property

        ''' <summary>
        ''' The minimum level required to equip an heirloom
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RequiredLevelMin As Integer
            Get
                Return GetItemTooltip.requiredLevelMin
            End Get
        End Property

        ''' <summary>
        ''' The maximum level required to equip an heirloom
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RequiredLevelMax As Integer
            Get
                Return GetItemTooltip.requiredLevelMax
            End Get
        End Property

        ''' <summary>
        ''' The level at which the heirloom's stats are currently being calculated for
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RequiredLevelCur As Integer
            Get
                Return GetItemTooltip.requiredLevelCur
            End Get
        End Property

        ''' <summary>
        ''' The ability, skill, or profession required to use the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RequiredAbility As String
            Get
                Return GetItemTooltip.requiredAbility
            End Get
        End Property

        ''' <summary>
        ''' Determines if the item is an heroic version
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Heroic As Boolean
            Get
                Return GetItemTooltip.heroic = 1
            End Get
        End Property

        ''' <summary>
        ''' The item's iLevel
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property ItemLevel As Integer
            Get
                Return GetItemTooltip.itemLevel
            End Get
        End Property

        ''' <summary>
        ''' The item's flavor text
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property FlavorText As String
            Get
                Return GetItemTooltip.desc
            End Get
        End Property

        ''' <summary>
        ''' The block value of the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>Only applies to shields, returns 0 otherwise</remarks>
        Public ReadOnly Property BlockValue As Integer
            Get
                Return GetItemTooltip.blockValue
            End Get
        End Property

        ''' <summary>
        ''' The amount of intellect given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusIntellect As Integer
            Get
                Return GetItemTooltip.bonusIntellect
            End Get
        End Property

        ''' <summary>
        ''' The amount of spirit given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusSpirit As Integer
            Get
                Return GetItemTooltip.bonusSpirit
            End Get
        End Property

        ''' <summary>
        ''' The amount of strength given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusStrength As Integer
            Get
                Return GetItemTooltip.bonusStrength
            End Get
        End Property

        ''' <summary>
        ''' The amount of stamina given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusStamina As Integer
            Get
                Return GetItemTooltip.bonusStamina
            End Get
        End Property

        ''' <summary>
        ''' The amount of agility given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusAgility As Integer
            Get
                Return GetItemTooltip.bonusAgility
            End Get
        End Property

        ''' <summary>
        ''' The amount of hit rating given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusHitRating As Integer
            Get
                Return GetItemTooltip.bonusHitRating
            End Get
        End Property

        ''' <summary>
        ''' The amount of critical strike rating given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusCritRating As Integer
            Get
                Return GetItemTooltip.bonusHitRating
            End Get
        End Property

        ''' <summary>
        ''' The amount of attack power given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusAttackPower As Integer
            Get
                Return GetItemTooltip.bonusAttackPower
            End Get
        End Property

        ''' <summary>
        ''' The amount of spell power given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusSpellPower As Integer
            Get
                Return GetItemTooltip.bonusSpellPower
            End Get
        End Property

        ''' <summary>
        ''' The amount of expertise rating given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusExpertiseRating As Integer
            Get
                Return GetItemTooltip.bonusExpertiseRating
            End Get
        End Property

        ''' <summary>
        ''' The amount of parry rating given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusParryRating As Integer
            Get
                Return GetItemTooltip.bonusParryRating
            End Get
        End Property

        ''' <summary>
        ''' The amount of armor penetration rating given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusArmorPenetrationRating As Integer
            Get
                Return GetItemTooltip.bonusArmorPenetration
            End Get
        End Property

        ''' <summary>
        ''' The amount of dodge rating given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusDodgeRating As Integer
            Get
                Return GetItemTooltip.bonusDodgeRating
            End Get
        End Property

        ''' <summary>
        ''' The amount of defense skill rating given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusDefenseSkillRating As Integer
            Get
                Return GetItemTooltip.bonusDefenseSkillRating
            End Get
        End Property

        ''' <summary>
        ''' The amount of resilience rating given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusResilienceRating As Integer
            Get
                Return GetItemTooltip.bonusResilienceRating
            End Get
        End Property

        ''' <summary>
        ''' The amount of block rating given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusBlockRating As Integer
            Get
                Return GetItemTooltip.bonusBlockRating
            End Get
        End Property

        ''' <summary>
        ''' The amount of haste rating given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusHasteRating As Integer
            Get
                Return GetItemTooltip.bonusHasteRating
            End Get
        End Property

        ''' <summary>
        ''' The amount of mana regeneration per 5 seconds given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusManaRegen As Integer
            Get
                Return GetItemTooltip.bonusManaRegen
            End Get
        End Property

        ''' <summary>
        ''' The amount of spell penetration rating given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusSpellPenetrationRating As Integer
            Get
                Return GetItemTooltip.bonusSpellPenetration
            End Get
        End Property

        ''' <summary>
        ''' The amount of block value given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>This does not count the inherent block value of shields.  See the BlockValue property.</remarks>
        Public ReadOnly Property BonusBlockValue As Integer
            Get
                Return GetItemTooltip.bonusBlockValue
            End Get
        End Property

        ''' <summary>
        ''' The amount of health regeneration per 5 seconds given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property BonusHealthRegen As Integer
            Get
                Return GetItemTooltip.bonusHealthRegen
            End Get
        End Property

        ''' <summary>
        ''' The amount of nature resistance given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property NatureResistance As Integer
            Get
                Return GetItemTooltip.natureResist
            End Get
        End Property

        ''' <summary>
        ''' The amount of shadow resistance given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property ShadowResistance As Integer
            Get
                Return GetItemTooltip.shadowResist
            End Get
        End Property

        ''' <summary>
        ''' The amount of frost resistance given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property FrostResistance As Integer
            Get
                Return GetItemTooltip.frostResist
            End Get
        End Property

        ''' <summary>
        ''' The amount of fire resistance given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property FireResistance As Integer
            Get
                Return GetItemTooltip.fireResist
            End Get
        End Property

        ''' <summary>
        ''' The amount of arcane resistance given by the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property ArcaneResistance As Integer
            Get
                Return GetItemTooltip.arcaneResist
            End Get
        End Property

        ''' <summary>
        ''' The identification number of the quest that is started by this item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property StartQuestID As Integer
            Get
                Return GetItemTooltip.startQuestId
            End Get
        End Property

        ''' <summary>
        ''' The properties of a gem
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property GemProperties As String
            Get
                Return GetItemTooltip.gemProperties
            End Get
        End Property

        ''' <summary>
        ''' The type of glyph, major or minor
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property GlyphType As String
            Get
                Return GetItemTooltip.glyphType
            End Get
        End Property

        ''' <summary>
        ''' The permanent enchantment on the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Enchantment As String
            Get
                Return GetItemTooltip.enchant
            End Get
        End Property

        ''' <summary>
        ''' The name of the skill required to use the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RequiredSkill As String
            Get
                If GetItemTooltip.requiredSkill.Count = 0 Then
                    Return Nothing
                Else
                    Return GetItemTooltip.requiredSkill.First.name
                End If
            End Get
        End Property

        ''' <summary>
        ''' The skill level required to use the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RequiredSkillLevel As Integer
            Get
                If GetItemTooltip.requiredSkill.Count = 0 Then
                    Return Nothing
                Else
                    Return GetItemTooltip.requiredSkill.First.rank
                End If
            End Get
        End Property

        ''' <summary>
        ''' Determines if the item is unique-equippable
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property UniqueEquippable As Boolean
            Get
                If GetItemTooltip.maxCount.Count = 0 Then
                    Return False
                Else
                    Return GetItemTooltip.maxCount.First.uniqueEquippable = 1
                End If
            End Get
        End Property

        ''' <summary>
        ''' If UniqueEquippable is True, then this is the maximum number of this item the player can equip at once.  If UniqueEquippable is False, then this is the maximum number of this item the player can own.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property MaxCount As Integer
            Get
                If GetItemTooltip.maxCount.Count = 0 Then
                    Return 0
                Else
                    Return GetItemTooltip.maxCount.First.maxCount
                End If
            End Get
        End Property

        ''' <summary>
        ''' The type of equippable inventory item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property InventoryType As Enums.InventoryType
            Get
                If GetItemTooltip.equipData.Count = 0 Then
                    Return Enums.InventoryType.NonEquipType
                Else
                    Return CType(GetItemTooltip.equipData.First.inventoryType, Enums.InventoryType)
                End If
            End Get
        End Property

        ''' <summary>
        ''' The number of slots the container has
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property ContainerSlots As Integer
            Get
                If GetItemTooltip.equipData.Count = 0 Then
                    Return 0
                Else
                    Return GetItemTooltip.equipData.First.containerSlots
                End If
            End Get
        End Property

        ''' <summary>
        ''' The subclass of the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Subclass As String
            Get
                If GetItemTooltip.equipData.Count = 0 Then
                    Return Nothing
                Else
                    Return GetItemTooltip.equipData.First.subclassName
                End If
            End Get
        End Property

        ''' <summary>
        ''' The item's weapon speed
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property WeaponSpeed As Double
            Get
                If GetItemTooltip.damageData.Count = 0 Then
                    Return 0
                Else
                    Return GetItemTooltip.damageData.First.speed
                End If
            End Get
        End Property

        ''' <summary>
        ''' The item's weapon DPS
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property WeaponDPS As Double
            Get
                If GetItemTooltip.damageData.Count = 0 Then
                    Return 0
                Else
                    Return GetItemTooltip.damageData.First.dps
                End If
            End Get
        End Property

        ''' <summary>
        ''' The suffix of the random enchantment
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RandomEnchantmentSuffix As String
            Get
                If GetItemTooltip.randomEnchantData.Count = 0 Then
                    Return Nothing
                Else
                    Return GetItemTooltip.randomEnchantData.First.suffix
                End If
            End Get
        End Property

        ''' <summary>
        ''' The list of the item's random enchantments
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RandomEnchantments As Collection(Of String)
            Get
                If GetItemTooltip.randomEnchantData.Count = 0 Then
                    Return New Collection(Of String)
                Else
                    Return (From e In GetItemTooltip.randomEnchantData.First.enchant Select e.enchant).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' Indicates that this item has bonus armor on it
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property HasBonusArmor As Boolean
            Get
                If GetItemTooltip.armor.Count = 0 Then
                    Return False
                Else
                    Return GetItemTooltip.armor.First.armorBonus = 1
                End If
            End Get
        End Property

        ''' <summary>
        ''' The total amount of armor on the item, including bonus armor
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>The Armory does not as of yet separate base armor from bonus armor</remarks>
        Public ReadOnly Property TotalArmor As Integer
            Get
                If GetItemTooltip.armor.Count = 0 Then
                    Return 0
                Else
                    Return GetItemTooltip.armor.First.armor
                End If
            End Get
        End Property

        ''' <summary>
        ''' The current durability of the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property CurrentDurability As Integer
            Get
                If GetItemTooltip.durability.Count = 0 Then
                    Return 0
                Else
                    Return GetItemTooltip.durability.First.current
                End If
            End Get
        End Property

        ''' <summary>
        ''' The max durability of the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Durability As Integer
            Get
                If GetItemTooltip.durability.Count = 0 Then
                    Return 0
                Else
                    Return GetItemTooltip.durability.First.max
                End If
            End Get
        End Property

        ''' <summary>
        ''' The list of races allowed to use this item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property AllowableRaces As Collection(Of String)
            Get
                If GetItemTooltip.allowableRaces.Count = 0 Then
                    Return New Collection(Of String)
                Else
                    Return (From r In GetItemTooltip.allowableRaces.First.race Select r.race).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' The list of classes allowed to use this item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property AllowableClasses As Collection(Of String)
            Get
                If GetItemTooltip.allowableClasses.Count = 0 Then
                    Return New Collection(Of String)
                Else
                    Return (From c In GetItemTooltip.allowableClasses.First.class Select c.class).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' The faction required to use the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RequiredFaction As String
            Get
                If GetItemTooltip.requiredFaction.Count = 0 Then
                    Return Nothing
                Else
                    Return GetItemTooltip.requiredFaction.First.name
                End If
            End Get
        End Property

        ''' <summary>
        ''' The standing with the faction required to use the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RequiredFactionStanding As Enums.FactionStandingType
            Get
                If GetItemTooltip.requiredFaction.Count = 0 Then
                    Return Enums.FactionStandingType.None
                Else
                    Return CType(GetItemTooltip.requiredFaction.First.rep, Enums.FactionStandingType)
                End If
            End Get
        End Property

        ''' <summary>
        ''' The bonus for matching all of the gem sockets for this item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>Currently returns nothing when querying on just the item ID due to an Armory bug</remarks>
        Public ReadOnly Property SocketBonus As String
            Get
                If GetItemTooltip.socketData.Count = 0 Then
                    Return Nothing
                Else
                    Return GetItemTooltip.socketData.First.socketMatchEnchant
                End If
            End Get
        End Property

        ''' <summary>
        ''' The required personal arena rating to use this item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RequiredPersonalArenaRating As Integer
            Get
                If GetItemTooltip.requiredPersonalArenaRating.Count = 0 Then
                    Return 0
                Else
                    Return GetItemTooltip.requiredPersonalArenaRating.First.personalArenaRating
                End If
            End Get
        End Property

        ''' <summary>
        ''' Indicates that the item is conjured
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Conjured As Boolean
            Get
                Return GetItemTooltip.conjured.Count > 0
            End Get
        End Property

        ''' <summary>
        ''' Information about the set the item belongs in
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property [Set] As SetData
            Get
                If GetItemTooltip.setData.Count = 0 Then
                    Return Nothing
                Else
                    Return (From sd In GetItemTooltip.setData
                            Select New SetData(sd.name,
                                               (From rs In sd.requiredSkill Select New SetRequiredSkill(rs.name, rs.rank, rs.hasSkill = 1)).ToCollection,
                                               (From i In sd.item Select New SetItem(i.name, i.equipped = 1)).ToCollection,
                                               (From sb In sd.setBonus Select New SetBonus(sb.desc, sb.threshold)).ToCollection)).First
                End If
            End Get
        End Property

        ''' <summary>
        ''' Information about the item's weapon damage
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property WeaponDamage As Collection(Of DamageData)
            Get
                If GetItemTooltip.damageData.Count = 0 Then
                    Return New Collection(Of DamageData)
                Else
                    Return (From d In GetItemTooltip.damageData.First.damage
                            Select New DamageData(CType(d.type, Enums.DamageTypeType), d.min, d.max)).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' Information about the spells that this item can perform
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Spells As Collection(Of SpellData)
            Get
                If GetItemTooltip.spellData.Count = 0 Then
                    Return New Collection(Of SpellData)
                Else
                    Return (From s In GetItemTooltip.spellData.First.spell
                            Select New SpellData(CType(s.trigger, Enums.SpellTriggerType), s.desc, s.charges)).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' Information about the sources of this item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Sources As Collection(Of ItemSource)
            Get
                Return (From [is] In GetItemTooltip.itemSource Select New ItemSource([is].areaId, [is].areaName, [is].creatureId, [is].creatureName, [is].difficulty, CType([is].dropRate, Enums.DropRateType), [is].reqLvl, [is].value)).ToCollection
            End Get
        End Property

        ''' <summary>
        ''' Information about the gem sockets in this item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Sockets As Collection(Of SocketData)
            Get
                If GetItemTooltip.socketData.Count = 0 Then
                    Return New Collection(Of SocketData)
                Else
                    Return (From s In GetItemTooltip.socketData.First.socket
                            Select New SocketData(s.color, s.enchant, s.icon, s.match = 1)).ToCollection
                End If
            End Get
        End Property

#End Region

#Region "Public Methods"

        ''' <summary>
        ''' Constructor to load an item tooltip with a known ID number
        ''' </summary>
        ''' <param name="intItemID"></param>
        ''' <remarks></remarks>
        Public Sub New(ByVal intItemID As Integer)
            ItemID = intItemID
            Character = Nothing
            Realm = Nothing
            Slot = Nothing
            Me.Load()
        End Sub

        ''' <summary>
        ''' Constructor to load a specific instance of an item tooltip
        ''' </summary>
        ''' <param name="intItemID"></param>
        ''' <param name="strCharacter"></param>
        ''' <param name="strRealm"></param>
        ''' <param name="istSlot"></param>
        ''' <remarks></remarks>
        Public Sub New(ByVal intItemID As Integer, ByVal strCharacter As String, ByVal strRealm As String, ByVal istSlot As Enums.ItemSlotType)
            ItemID = intItemID
            Character = strCharacter
            Realm = strRealm
            Slot = istSlot
            Me.Load()
        End Sub

        ''' <summary>
        ''' Loads the item tooltip from the Armory
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Load()
            Dim strKey As String = String.Format(CultureInfo.InvariantCulture, "LibWoWArmory.ItemTooltip.{0}.{1}.{2}.{3}", ItemID, Character, Realm, Slot.ToString)
            If Cache.Cache(strKey) Is Nothing Then
                MyBase.Retrieve()

                Dim xsSerializer As New XmlSerializer(itPage.GetType)

                Using srXML As New StringReader(MyBase.Data)
                    itPage = CType(xsSerializer.Deserialize(srXML), Schema.page)
                End Using

                Cache.Cache.Insert(strKey, itPage, Nothing, Date.UtcNow.AddDays(1), Nothing, Caching.CacheItemPriority.Normal, Nothing)
            Else
                itPage = CType(Cache.Cache(strKey), Schema.page)
            End If

            If itPage.ItemTooltips Is Nothing Then
                Throw New ArgumentException("The item you are trying to retrieve does not exist.")
            End If

            If itPage.ItemTooltips.First.ItemTooltip Is Nothing Then
                Throw New ArgumentException("The item you are trying to retrieve does not exist.")
            End If
        End Sub

#End Region

#Region "Private Methods"

        Private Function GetItemTooltips() As Collection(Of Schema.itemTooltip)
            Return (From it In itPage.itemTooltips Where it.itemTooltip.Count > 0 Select it.itemTooltip.First).ToCollection
        End Function

        Private Function GetItemTooltip() As Schema.itemTooltip
            Return GetItemTooltips.First
        End Function

#End Region

    End Class

End Namespace